package avicit.bdp.dds.api.controller;

import avicit.bdp.core.constant.Constants;
import avicit.bdp.dds.api.service.AlgoNodesService;
import avicit.bdp.dds.dao.entity.AlgoNodes;
import avicit.platform6.api.system.ConvertColumnClient;
import avicit.platform6.api.system.impl.SystemConstant;
import avicit.platform6.commons.utils.BusinessUtil;
import avicit.platform6.core.rest.msg.QueryRespBean;
import avicit.platform6.core.rest.msg.ResponseMsg;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import springfox.documentation.annotations.ApiIgnore;

import org.apache.commons.collections4.MapUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 算法库管理REST接口
 */
@RestController
@Api(tags = "算法库管理REST接口")
@RequestMapping("/api/bdp/dds/nodes")
public class AlgoNodesRest {

    @Autowired
    private AlgoNodesService algoNodesService;

    @Autowired
    private ConvertColumnClient convertColumnClient;

    /**
     * 新增算法库，提供给数据工作台使用
     */
    @ApiOperation(value = "新增算法库，提供给数据工作台使用")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "name", value = "名称", dataType = "String"),
            @ApiImplicitParam(name = "programType", value = "程序类型", dataType = "Int"),
            @ApiImplicitParam(name = "typeId", value = "分类id", dataType = "String"),
            @ApiImplicitParam(name = "className", value = "类名称", dataType = "String"),
            @ApiImplicitParam(name = "open", value = "是否共享", dataType = "Int"),
            @ApiImplicitParam(name = "remark", value = "描述", dataType = "String"),
            @ApiImplicitParam(name = "content", value = "内容", dataType = "String"),
            @ApiImplicitParam(name = "file", value = "文件", dataType = "MultipartFile"),
            @ApiImplicitParam(name = "projectId", value = "数据空间id", dataType = "String"),
            @ApiImplicitParam(name = "params", value = "参数json", dataType = "String")
    })
    @PostMapping("/insertNode")
    public ResponseMsg<String> insertNode(String name, Integer programType, String typeId, String className,
                                          Integer open, String remark, String content, MultipartFile file,
                                          String projectId, String params) {
        ResponseMsg<String> responseMsg = new ResponseMsg<>();
        responseMsg.setResponseBody(
                algoNodesService.insertNode(name, programType, typeId, className, open, remark, content, file,
                        projectId, params));
        return responseMsg;
    }

    /**
     * 新增算法库，提供给数据计算使用
     */
    @PostMapping("/insertNode2")
    @ApiOperation(value = "新增算法库，提供给数据计算使用")
    public ResponseMsg<String> insertNode(@RequestBody AlgoNodes algoNodes) {
        ResponseMsg<String> responseMsg = new ResponseMsg<>();

        responseMsg.setResponseBody(algoNodesService.insertNode(algoNodes));

        return responseMsg;
    }

    /**
     * 修改算法库
     */
    @PostMapping("/updateNode")
    @ApiOperation(value = "修改算法库")
    public ResponseMsg<String> updateNode(@RequestBody AlgoNodes algoNodes) {
        ResponseMsg<String> responseMsg = new ResponseMsg<>();
        algoNodesService.updateNode(algoNodes);
        return responseMsg;
    }

    /**
     * 删除算法库对象
     */
    @ApiOperation(value = "按主键单条删除")
    @ApiImplicitParam(name = "id", value = "id", dataType = "String", paramType = "body", required = true)
    @PostMapping("/deleteNode")
    public ResponseMsg<Integer> deleteNode(@ApiIgnore @RequestBody Map<String, String> queryMap) {
        ResponseMsg<Integer> responseMsg = new ResponseMsg<>();
        algoNodesService.deleteNode(queryMap.get("id"));
        return responseMsg;
    }

    /**
     * 共享/取消共享
     */
    @ApiOperation(value = "共享")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "id", dataType = "String", paramType = "body"),
            @ApiImplicitParam(name = "open", value = "共享状态", dataType = "Int", paramType = "body")
    })
    @PostMapping("/updateOpen")
    public ResponseMsg<String> updateOpen(@ApiIgnore @RequestBody Map<String, Object> queryMap) {
        ResponseMsg<String> responseMsg = new ResponseMsg<>();
        String id = (String) queryMap.get("id");
        Integer open = (Integer) queryMap.get("open");
        algoNodesService.updateOpen(id, open);
        return responseMsg;
    }

    /**
     * 查看算法节点详情
     */
    @ApiOperation(value = "查看算法节点详情")
    @ApiImplicitParam(name = "id", value = "id", dataType = "String")
    @GetMapping("/getAlgoNodeInfo")
    public ResponseMsg<AlgoNodes> getAlgoNodeInfo(@RequestParam String id) {
        ResponseMsg<AlgoNodes> responseMsg = new ResponseMsg<>();

        AlgoNodes queryRet = algoNodesService.getAlgoNodeInfo(id);
        valueConvert(Arrays.asList(queryRet));
        responseMsg.setResponseBody(queryRet);

        return responseMsg;
    }

    /**
     * 查询右侧数据
     */
    @ApiOperation(value = "查询右侧数据")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "分类Id", name = "typeId", dataType = "String"),
            @ApiImplicitParam(value = "项目id", name = "projectId", dataType = "String"),
            @ApiImplicitParam(value = "查询关键字", name = "keyWords", dataType = "String"),
            @ApiImplicitParam(value = "当前页", name = "pageNo", dataType = "Int"),
            @ApiImplicitParam(value = "每页大小", name = "pageSize", dataType = "Int")
    })
    @GetMapping("/getList")
    public ResponseMsg<QueryRespBean<AlgoNodes>> getList(
            @RequestParam String typeId,
            @RequestParam String projectId,
            @RequestParam(required = false) String keyWords,
            @RequestParam(defaultValue = "1", required = false) Integer pageNo,
            @RequestParam(defaultValue = "10", required = false) Integer pageSize) {

        ResponseMsg<QueryRespBean<AlgoNodes>> responseMsg = new ResponseMsg<>();
        QueryRespBean<AlgoNodes> result = algoNodesService.getList(typeId, projectId, keyWords, pageNo, pageSize);
        valueConvert(result.getResult());
        responseMsg.setResponseBody(result);
        return responseMsg;
    }

    /**
     * 通过平台API将字段值转换为名称，包括通用选择组件、通用代码
     *
     * @param algoNodesList algoNodesList
     */
    private void valueConvert(List<AlgoNodes> algoNodesList) {
        //循环组装请求数据
        Map<String, Set<String>> convertFormData = new HashMap<>();
        for (AlgoNodes algoNodes : algoNodesList) {
            BusinessUtil.createConvertSet(convertFormData, SystemConstant.USER, algoNodes.getCreatedBy());
            BusinessUtil.createConvertSet(convertFormData, Constants.BDP_DATA_SECRET_LEVEL_KEY, algoNodes.getSecretLevel());
        }
        if (convertFormData.size() > 0) {
            //获取请求结果
            Map<String, Map<String, String>> convertResultData = convertColumnClient.replace(convertFormData);
            //循环设置Alias或Name的值
            for (AlgoNodes algoNodes : algoNodesList) {
                algoNodes.setUsername(BusinessUtil.convertFormat(convertResultData, SystemConstant.USER,
                        algoNodes.getCreatedBy()));
                algoNodes.setSecretLevelName(BusinessUtil.convertFormat(
                        convertResultData, Constants.BDP_DATA_SECRET_LEVEL_KEY, algoNodes.getSecretLevel()));
            }
        }
    }


    /**
     * 查询可导入数据
     */
    @ApiOperation(value = "查询可导入数据")
    @ApiImplicitParams({
            @ApiImplicitParam(value = "项目id", name = "projectId", dataType = "String"),
            @ApiImplicitParam(value = "查询关键字", name = "keyWords", dataType = "String"),
            @ApiImplicitParam(value = "当前页", name = "pageNo", dataType = "Int"),
            @ApiImplicitParam(value = "每页大小", name = "pageSize", dataType = "Int")
    })
    @GetMapping("/getListImport")
    public ResponseMsg<QueryRespBean<AlgoNodes>> getListExport(
            @RequestParam String projectId,
            @RequestParam(required = false) String keyWords,
            @RequestParam(defaultValue = "1", required = false) Integer pageNo,
            @RequestParam(defaultValue = "10", required = false) Integer pageSize) {
        ResponseMsg<QueryRespBean<AlgoNodes>> responseMsg = new ResponseMsg<>();
        QueryRespBean<AlgoNodes> result = algoNodesService.getListExport(projectId, keyWords, pageNo, pageSize);
        valueConvert(result.getResult());
        responseMsg.setResponseBody(result);
        return responseMsg;
    }


    /**
     * 导入
     */
    @ApiOperation(value = "导入")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "ids", value = "id集合", dataType = "String",  paramType = "body"),
            @ApiImplicitParam(name = "projectId", value = "数据空间id", dataType = "String", paramType = "body"),
            @ApiImplicitParam(name = "typeId", value = "分类id", dataType = "String", paramType = "body")
    })
    @PostMapping("/importNode")
    public ResponseMsg<Integer> importNode(@ApiIgnore @RequestBody Map<String, String> queryMap) {
        ResponseMsg<Integer> responseMsg = new ResponseMsg<>();
        String projectId = queryMap.get("projectId");
        String typeId = queryMap.get("typeId");
        String ids = queryMap.get("ids");
        algoNodesService.importNode(ids, typeId, projectId);
        return responseMsg;
    }

    /**
     * 判断算法库名称是否重复
     */
    @ApiOperation(value = "判断算法库名称是否重复")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "id", dataType = "String",  paramType = "body"),
            @ApiImplicitParam(name = "projectId", value = "数据空间id", dataType = "String", paramType = "body"),
            @ApiImplicitParam(name = "name", value = "名称", dataType = "String", paramType = "body")
    })
    @PostMapping("/isSameName")
    public ResponseMsg<Boolean> isSameName(@ApiIgnore @RequestBody Map<String, String> queryMap) {
        ResponseMsg<Boolean> responseMsg = new ResponseMsg<>();
        String id = MapUtils.getString(queryMap, "id", "");
        String name = MapUtils.getString(queryMap, "name", "");
        String projectId = MapUtils.getString(queryMap, "projectId", "");
        Boolean flag = algoNodesService.isSameName(id, name, projectId);
        responseMsg.setResponseBody(flag);
        return responseMsg;
    }

    @ApiOperation(value = "下载python文件")
    @ApiImplicitParam(value = "算法库id", name = "nodeId", dataType = "String")
    @GetMapping("/download")
    public void download(@RequestParam String nodeId, HttpServletResponse response) {
        this.algoNodesService.download(nodeId, response);
    }

}
